#pragma once

#include <mutex>
#include <unordered_map>
#include <vector>
#include <list>


#include "page.h"              // Page 类定义
#include "replacer.h"          // Replacer 接口
#include "disk_manager.h"      // DiskManager 类
#include "common.h"           // 公共类型定义

// 页帧 ID（缓冲池中的索引）
using frame_id_t = int32_t;

// 无效帧 ID
// static constexpr frame_id_t INVALID_FRAME_ID = -1;

// 缓冲池管理器类
class BufferPoolManager {
public:
  /**
   * 构造函数
   * @param pool_size 缓冲池中页帧的数量
   * @param replacer 替换算法实现（如 LRUReplacer）
   * @param disk_manager 磁盘管理器
   */
  BufferPoolManager(size_t pool_size, std::unique_ptr<Replacer> replacer, DiskManager* disk_manager);

  /**
   * 析构函数：释放资源，刷回所有脏页
   */
  ~BufferPoolManager();

  /**
   * 获取指定页的指针。如果页不在缓冲池中，则从磁盘加载。
   * 如果页不存在且需要分配，则由上层逻辑控制（见 new_page）。
   *
   * @param page_id 请求的页 ID
   * @return Page* 指向请求页的指针，若失败返回 nullptr
   */
  Page* FetchPage(page_id_t page_id);

  /**
   * 释放对页的引用。调用后表示当前线程不再使用该页。
   *
   * @param page_id 页 ID
   * @param is_dirty 是否修改过（脏页）
   * @return 是否成功
   */
  bool UnpinPage(page_id_t page_id, bool is_dirty = false);

  /**
   * 将指定页的内容强制写回磁盘（即使未修改，也会触发写入）
   *
   * @param page_id 页 ID
   * @return 是否成功
   */
  bool FlushPage(page_id_t page_id);

  /**
   * 将所有脏页写回磁盘
   */
  size_t FlushAllPages();

  /**
   * 分配一个新页（用于创建新数据页）
   *
   * @return 新页的 ID，若失败返回 INVALID_PAGE_ID
   */
  page_id_t NewPage();

  /**
   * 删除一个页（并释放其在磁盘上的空间）
   *
   * @param page_id 要删除的页 ID
   * @return 是否成功
   */
  bool DeletePage(page_id_t page_id);

  /**
   * 获取指定页的当前 pin_count（调试用）
   */
  int GetPinCount(page_id_t page_id) const;

  /**
   * 检查页是否为脏页（调试用）
   */
  bool IsDirty(page_id_t page_id) const;

  /**
   * 获取缓冲池中已分配的页数（调试用）
   */
  size_t GetPageCount() const;

private:
  /** 私有方法：查找页是否已在缓冲池中 */
  Page* FindPage(page_id_t page_id);

  /** 私有方法：选择一个受害者帧用于加载新页 */
  frame_id_t FindVictimFrame();

  /** 缓冲池大小（页帧数量） */
  const size_t pool_size_;

  /** 页帧数组：缓冲池的主体，存放实际页数据 */
  Page* pages_;

  /** 页表：从 page_id 映射到 frame_id */
  std::unordered_map<page_id_t, frame_id_t> page_table_;

  /** 替换器：负责选择淘汰页 */
  // Replacer* replacer_;
  std::unique_ptr<Replacer> replacer_;  // 改成 unique_ptr

  /** 空闲帧列表：存储当前未被使用的帧编号 */
  std::list<frame_id_t> free_list_;

  /** 磁盘管理器：用于读写磁盘 */
  DiskManager* disk_manager_;

  /** 互斥锁：保护缓冲池共享数据结构 */
  mutable std::mutex latch_;

  // 禁用拷贝构造和赋值
  BufferPoolManager(const BufferPoolManager&) = delete;
  BufferPoolManager& operator=(const BufferPoolManager&) = delete;
};